package org.example.springoauth2.securitycommon.config.resource;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import org.example.springoauth2.securitycommon.config.PermitAllUrlProperties;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author hzq
 * @date 2021/10/11 11:53
 */
@AllArgsConstructor
public class EnhanceBearerTokenExtractor extends BearerTokenExtractor {

    private final PermitAllUrlProperties permitAllUrlProperties;

    /**
     * 不需要认证的接口不提取认证信息
     */
    @Override
    public Authentication extract(HttpServletRequest request) {
        // inner.value() = false 时不提取token
        boolean result = permitAllUrlProperties.getIgnoreUrls().stream().anyMatch(predicate(request));
        return result ? null : super.extract(request);
    }

    private Predicate<String> predicate(HttpServletRequest request) {
        return (String url) -> {
            List<String> strings = StrUtil.splitTrim(url, PermitAllUrlProperties.SEPARATOR);
            // 1. 判断路径是否匹配 /home
            boolean match = PermitAllUrlProperties.PATHMATCHER.match(strings.get(0), request.getRequestURI());
            // 2. 判断路径是否匹配 && 判断inner.value() /home|true
            if (strings.size() == 2) {
                return match && !Boolean.parseBoolean(strings.get(1));
            }
            // 3. 判断方法是否匹配 && 判断路径是否匹配 && 判断inner.value() /home|GET|true
            if (strings.size() == 3) {
                return CollUtil.contains(StrUtil.splitTrim(strings.get(1), StrUtil.COMMA), request.getMethod())
                        && match && !Boolean.parseBoolean(strings.get(2));
            }
            return match;
        };
    }
}
